//
//  String.h
//  LightBasic
//
//  Created by Albert on 05/04/2011.
//  Copyright 2011 LightBasic Development Team. All rights reserved.
//
#pragma once

namespace lbc {
    
    /// Simpel string class that also contains a hash
    struct StringRef
    {
        /// the hash function
        typedef boost::hash<std::string> hash_func; 
        
        // default
        StringRef() : m_hash(0) {}
        
        // copy
        StringRef(const StringRef & str) : m_str(str.m_str), m_hash(str.m_hash) {}
        
        // from std::string
        StringRef(const std::string & str) : m_str(str), m_hash(0) {}
        
        // from const char *
        StringRef(const char * str) : m_str(str), m_hash(0) {}
        
        // from const char *
        template<class InputIterator> StringRef(InputIterator begin, InputIterator end) : m_str(begin, end), m_hash(0) {}
        
        // cast to string
        operator const std::string & () const { return m_str; }
        
        // call operator
        const std::string & str() const { return m_str; }
        
        // Get hash
        size_t GetHash() const
        {
            if (m_hash == 0) {
                m_hash = hash_func()(m_str);
            }
            return m_hash;
        }
        
        
        /// equal
        bool operator == (const StringRef & rhs) const
        {
            return m_str == rhs.m_str;
        }
        
        
        /// not equal
        bool operator != (const StringRef & rhs) const
        {
            return m_str != rhs.m_str;
        }
        
        /// equal
        bool operator == (const std::string & rhs) const
        {
            return m_str == rhs;
        }
        
        
        /// not equal
        bool operator != (const std::string & rhs) const
        {
            return m_str != rhs;
        }
        
        
        /// equal
        bool operator == (const char * rhs) const
        {
            return m_str == rhs;
        }
        
        
        /// not equal
        bool operator != (const char * rhs) const
        {
            return m_str != rhs;
        }
        
        
    private:
        std::string m_str;
        mutable size_t m_hash;
    };
    
    
    /// Functor for StringRef hash
    struct StringRefHash
    {
        size_t operator() (const StringRef & str) const
        {
            return str.GetHash();
        }
    };
}
